Coroutine(協程)可以看作輕量級的 thread(執行緒),執行緒是作業系統負責調度,協程則是應用程式負責調度,因為少了 system call 等步驟,切換的開銷比起執行緒小。
非同步執行遇上生命週期變得更複雜,可能在背景下載到一半手機螢幕熄掉,APP 在背景被中止,這時候就應該取消下載的協程,好在 Android Kotlin extension 已經幫我們處理好。
lifecycleScope
viewModelScope
程式預設跑在主執行緒上,處理程式 UI 也不例外,如果在主執行緒上執行非常耗時的工作,就會無法處理 UI 互動,導致傳說中的「應用程式沒有回應 (ANR)」
為了不阻塞 UI 互動,需要使用不同的調度器(Dispatcher)把協程綁定到不同的執行緒,預設有 Default
、Main
、IO
三種 Dispatcher,Unconfined
很少用到。
在 launch()
傳入 Dispatchers.IO
就能讓協程綁定在不同於 UI 的執行緒。
class CourseSearchViewModel(
private val repo: FcuRepository
) : ViewModel(), KoinComponent {
var state by mutableStateOf(SearchFilter(111, 1))
private set
fun search(dispatcher: CoroutineDispatcher = Dispatchers.IO) {
val filter = state.copy()
viewModelScope.launch(dispatcher) {
repo.search(filter)?.let { result = it.postFilter(filter) }
}
}
}